<?php

namespace Wonfu\Process;

use Psr\Log\LoggerInterface;

class Pm
{
    /**
     * @var LoggerInterface
     */
    private static $logger;

    public static $pids;

    public static function setLogger(LoggerInterface $logger){
        self::$logger = $logger;
    }

    /**
     * 创建多进程任务
     * @param callable $fn  子进程执行方法
     * @param mixed $param  参数列表
     */
    public static function fork(callable $fn, ...$param)
    {
        $pid = pcntl_fork();
        if ($pid == -1) {
            //创建子进程失败
            die('创建子进程失败');
        } else if ($pid) {
            self::$pids[] = $pid;
                //父进程的到子进程号 父进程逻辑
            $ppid = posix_getpid();
            if(self::$logger instanceof LoggerInterface){
                self::$logger->info("进程 {$ppid} 创建子进程:" . $pid);
            }
        } else {
            //子进程逻辑
            call_user_func_array($fn, $param);
            exit(0);
        }
    }

    public static function waitChildCompleted()
    {
        while (($pid = pcntl_waitpid(0, $status)) != -1) {
            $status = pcntl_wexitstatus($status);
            if(self::$logger instanceof LoggerInterface){
                self::$logger->info("子进程$pid 完成 状态 $status");
            }
        }
    }

    /**
     * 向所有子进程发送信号
     */
    public static function killall($signal){

        foreach (self::$pids as $pid){
            posix_kill($pid,$signal);
        }
    }

}